#include "Subsystems/BlockBehaviors/SubsystemFenceBlockBehavior.h"
#include "Subsystems/SubsystemTerrain.h"
#include "Managers/BlocksManager.h"
#include "Terrain/Terrain.h"
#include "Blocks/FenceBlock.h"

#include "GameSingleton.h"
#include "Log.h"


namespace PocketSurvival
{
    void SubsystemFenceBlockBehavior::onNeighborBlockChanged(int32_t x, int32_t y, int32_t z, int32_t neighborX, int32_t neighborY, int32_t neighborZ)
    {
		int32_t cellValue = m_terrain->getCellValue(x, y, z);
		updateVariant(cellValue, x, y, z);
    }

    void SubsystemFenceBlockBehavior::onBlockAdded(int32_t value, int32_t newValue, int32_t x, int32_t y, int32_t z)
    {
        updateVariant(value, x, y, z);
    }

    void SubsystemFenceBlockBehavior::updateVariant(int32_t value, int32_t x, int32_t y, int32_t z)
    {
		int32_t num = Terrain::ExtractContents(value);
		FenceBlock *fenceBlock = GameSingleton::blocksManager->blocks[num]->asBlock<FenceBlock*>();
		if (fenceBlock != nullptr)
		{
			int32_t cellValue  = m_terrain->getCellValue(x + 1, y, z);
			int32_t cellValue2 = m_terrain->getCellValue(x - 1, y, z);
			int32_t cellValue3 = m_terrain->getCellValue(x, y, z + 1);
			int32_t cellValue4 = m_terrain->getCellValue(x, y, z - 1);
			int32_t num2 = 0;
			if (fenceBlock->shouldConnectTo(cellValue))
			{
				num2++;
			}
			if (fenceBlock->shouldConnectTo(cellValue2))
			{
				num2 += 2;
			}
			if (fenceBlock->shouldConnectTo(cellValue3))
			{
				num2 += 4;
			}
			if (fenceBlock->shouldConnectTo(cellValue4))
			{
				num2 += 8;
			}
			int32_t data   = Terrain::ExtractData(value);
			int32_t value2 = Terrain::ReplaceData(value, FenceBlock::SetVariant(data, num2));
            m_terrain->changeCell(x, y, z, value2);
		}
    }

    void SubsystemFenceBlockBehavior::load(const nlohmann::json& json)
    {
        m_terrain = GameSingleton::singletonPtr->getSingleton<SubsystemTerrain>();
    }

    static const std::string subsystemName = "FenceBlockBehavior";
    const std::string& SubsystemFenceBlockBehavior::getName() const
    {
        return subsystemName;
    }

} // namespace PocketSurvival
